package com.david.trade.common;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;

/**
 * @author wangjijiang
 * @date 2020/6/18 17:10
 */
public class LRUCache {

    private int maxSize;

    private int size;

    private Map<Serializable, LRUObject> map;

    private LinkedList<LRUObject> queue;

    public LRUCache(int maxSize) {
        this.maxSize = maxSize;
        map = new HashMap<>(maxSize);
        queue = new LinkedList<>();
    }

    public LRUObject add(LRUObject object) {
        map.put(object.getKey(), object);
        queue.add(object);
        if (size > this.maxSize) {
            LRUObject head = queue.poll();
            map.remove(head.getKey());
            return head;
        } else {
            size++;
            return null;
        }
    }

    public boolean contain(Serializable key) {
        return map.containsKey(key);
    }

    public LRUObject get(Serializable key) {
        return map.get(key);
    }

    public Map<Serializable, LRUObject> element() {
        return map;
    }

    public boolean update(LRUObject object) {
        if (object.getKey().equals(queue.getFirst().getKey())) {
            queue.addLast(object);
            queue.removeFirst();
            return true;
        }
        return this.map.containsKey(object.getKey());
    }

    public LRUObject remove(Serializable key) {
        LRUObject object = this.map.remove(key);
        if (object == null) {
            return null;
        }
        Iterator<LRUObject> it = queue.iterator();
        while (it.hasNext()) {
            object = it.next();
            if (object.getKey().equals(key)) {
                it.remove();
                size--;
                break;
            }
        }
        return object;
    }
}
